package br.com.foxinline.servico;

import br.com.foxinline.generico.ServicoGenerico;
import br.com.foxinline.modelo.Anexo;
import br.com.foxinline.modelo.Quadra;
import br.com.foxinline.modelo.Setor;
import br.com.foxinline.util.Msg;
import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 *
 * @author laverson
 */
@Stateless
public class QuadraServico extends ServicoGenerico<Quadra> {

    private Long quantidadeRegistrosResults;

    public QuadraServico() {
        super(Quadra.class);
    }

    @Override
    public void save(Quadra entity) {
        List<Quadra> result = find(entity, 0, 1);

        if (result != null && !result.isEmpty()) {
            Msg.messagemError("Já existe uma quadra cadastrada com o número " + entity.getNumero() + " neste setor !");
        } else {
            Msg.messagemInfo(Msg.SuccessFull);
            super.save(entity);
        }
    }

    @Override
    public void update(Quadra entity) {
        super.update(entity);
        updateAnexos(entity);
    }

    @Override
    public void updateAnexos(Quadra p) {

        p.setCroqui(getAnexos(p));
        super.updateAnexos(p);
    }

    public Anexo getAnexos(Quadra q) {
        try {
            String sql = "select a from " + q.getClass().getSimpleName() + " q join q.croqui a where q.id = " + q.getId();
            return (Anexo) getEntityManager().createQuery(sql).getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    public List<Quadra> find(Setor setor) {

        if (setor != null && setor.getId() != null) {
            String sql = "SELECT q FROM " + Quadra.class.getSimpleName() + " q JOIN q.setor setor "
                    + "WHERE q.setor.id = :setorId and q.ativo = true "
                    + "ORDER BY q.numero";

            Query query = getEntityManager().createQuery(sql);
            query.setParameter("setorId", setor.getId());

            return query.getResultList();
        }

        return new ArrayList<Quadra>();
    }

    public List<Quadra> autoComplete(String query) {
        return findByName(query, null);
    }

    public List<Quadra> findByName(String numero, Setor setor) {
        String sql = "select q from Quadra q";

        if (setor != null) {
            sql += " JOIN q.setor s ";
        }

        sql += " where q.numero = " + numero.trim();

        if (setor != null) {
            sql += " and s.numero = " + setor.getNumero();
        }

        List<Quadra> results = getEntityManager().createQuery(sql).getResultList();
        return results;
    }

    public List<Quadra> autocomplete(String numero) {
        List<Quadra> results;
        String sql = "SELECT q FROM Quadra q WHERE q.numero = :numero";
        Query query = getEntityManager().createQuery(sql).setMaxResults(50);

        if (numero != null) {
            query.setParameter("numero", numero);
        }

        results = query.getResultList();

        if (results == null || results.isEmpty()) {
            return new ArrayList<Quadra>();
        }

        return results;
    }

    @Override
    public List<Quadra> find(Quadra entidade, Integer first, Integer pageSize) {
        String select = "SELECT q ";
        String sql = "FROM " + Quadra.class.getSimpleName() + " q JOIN q.setor s ";
        String orderBy = "ORDER BY q.numero ASC, s.numero ASC";

        Setor setor = null;

        if (entidade.getSetor() != null) {
            setor = entidade.getSetor();
        }

        sql += " WHERE ";

        if (entidade.getNumero() != null) {
            sql += "q.numero = :numero AND ";
        }

        if (setor != null) {
            if (setor.getId() != null) {
                sql += "s.id = :setorId AND ";
            }
            if (setor.getNumero() != null) {
                sql += "s.numero = :setorNumero AND ";
            }
        }

        sql += "q.ativo = TRUE ";

        Query query = getEntityManager().createQuery(select.concat(sql).concat(orderBy));

        setQuantidadeRegistros(sql, entidade, query);

        setParameters(entidade, query);

        if (first != null && pageSize != null) {
            query.setFirstResult(first).setMaxResults(pageSize);
        }

        return query.getResultList();
    }

    @Transient
    private void setParameters(Quadra entidade, Query query) {
        if (entidade.getNumero() != null) {
            query.setParameter("numero", entidade.getNumero());
        }

        Setor setor = null;

        if (entidade.getSetor() != null) {
            setor = entidade.getSetor();
        }

        if (setor != null) {
            if (setor.getId() != null) {
                query.setParameter("setorId", setor.getId());
            }
            if (setor.getNumero() != null) {
                query.setParameter("setorNumero", setor.getNumero());
            }
        }
    }

    private void setQuantidadeRegistros(String sql, Quadra entidade, Query query) {

        String select = "SELECT count(q) ";

        query = getEntityManager().createQuery(select + sql);

        setParameters(entidade, query);

        quantidadeRegistrosResults = (Long) query.getSingleResult();
    }

    @Override
    public Long quantidadeRegistros() {
        return quantidadeRegistrosResults;
    }
}
